package model;

import java.util.ArrayList;
import java.util.List;

import common.MCore;
import common.MElement;

import expression.MClassCard;
import expression.MClassSelfCard;

public class MClass extends MElement {
	private String name;
	private int id;
	private boolean mAbstract;
	private MClass superClass;
	private List<MClass> subClasses;
	private MClassCard cardinality;
	private MClassSelfCard selfCardinality;
	private int firstObject;
	private List<MDefinedObject> objects;
	
	public MClass(MCore core, String n, boolean a, MClass c) {
		super(core);
		name = n;
		mAbstract = a;
		superClass = c;
		if (c != null)
			c.subClasses.add(this);
		subClasses = new ArrayList<MClass>();
		
		cardinality = new MClassCard(this);		
		selfCardinality = new MClassSelfCard(this);
		
		firstObject = 0;
		objects = new ArrayList<MDefinedObject>();
	}

	public String getName() {
		return name;
	}
	
	public int getId() {
		return id;
	}
	
	public boolean isAbstract() {
		return mAbstract;
	}
	
	public MClass getSuperClass() {
		return superClass;
	}
	
	public List<MClass> getAllSuperClasses() {
		List<MClass> sc = new ArrayList<MClass>();

		if (superClass != null) {
			sc.add(superClass);
			sc.addAll(superClass.getAllSuperClasses());
		}
		
		return sc;
	}
	
	public List<MClass> getSubClasses() {
		return subClasses;
	}
	
	public MClassCard getCardinality() {
		return cardinality;
	}
	
	public MClassSelfCard getSelfCardinality() {
		return selfCardinality;
	}
	
	public void initId(int id) {
		// TODO
	}

	public String toText() {
		String s = "class ";
		
		if (mAbstract)
			s += "abstract ";
		s += name;
		
		if (superClass != null)
			s += " extends " + superClass.getName();
		
		return s;
	}
	
	public String toString() {
		String s = "class ";
		
		if (mAbstract)
			s += "abstract ";
		s += name;
		
		if (superClass != null)
			s += " extends " + superClass.getName();
		
		s += " :";
		for (MDefinedObject o: objects) {
			s += " " + o.getName();
		}
		
		return s;		
	}
	
	public int getFirstObject() {
		return firstObject;
	}
	
	public MDefinedObject addObject(String n) {
		MDefinedObject o = new MDefinedObject(this, n);
		objects.add(o);
		return o;
	}
	
	public List<MDefinedObject> getObjects() {
		return objects;
	}
	
	public MDefinedObject getObject(String n) {
		for (MDefinedObject o: objects) {
			if (n.equals(o.getName())) {
				return o;
			}
		}
		return null;
	}	
}
